package site.luojie.core.factory;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import site.luojie.core.annotation.Autowired;
import site.luojie.core.annotation.Component;
import site.luojie.utils.TransactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Description: 代理对象工厂
 * @Author jie.luo
 * @Create: 2020-05-02 08:42
 **/
@Component
public class ProxyFactory {

    @Autowired
    private TransactionManager transactionManager;

    public Object getProxy(Object object) {

        Class<?>[] interfaces = object.getClass().getInterfaces();
        if (null != interfaces && interfaces.length > 0) {
            return getJdkProxy(object);
        } else {
            return getCglibProxy(object);
        }
    }

    public Object getJdkProxy(Object object) {
        Object o = Proxy.newProxyInstance(this.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                Object invoke = null;
                try {
                    System.out.println("getJdkProxy.....开启事务");
                    transactionManager.beginTransaction();

                    invoke = method.invoke(object, args);

                    System.out.println("getJdkProxy.....提交事务");
                    transactionManager.commitTransaction();
                } catch (Exception e) {
                    System.out.println("getJdkProxy.....回滚事务事务");
                    transactionManager.rollbackTransaction();
                    e.printStackTrace();
                    throw e;
                }
                return invoke;
            }
        });

        return o;
    }

    public Object getCglibProxy(Object object) {

        Object o = Enhancer.create(object.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                Object result = null;

                try {
                    System.out.println("getCglibProxy.....开启事务");
                    transactionManager.beginTransaction();

                    result = method.invoke(object, objects);

                    System.out.println("getCglibProxy.....提交事务");
                    transactionManager.commitTransaction();
                } catch (Exception e) {
                    System.out.println("getCglibProxy.....回滚事务事务");
                    transactionManager.rollbackTransaction();
                    e.printStackTrace();
                    throw e;
                }

                return result;
            }
        });

        return o;
    }

}
